﻿
using Models.Common;
using Models.Device;
using Models.ScanNetWorkMac;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using GateWayCloodService.Device;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UtilsORM;
using GateWayCloodService.CloudCenter;
using UtilsBase;
using UtilsORM.MySql_IotGateway;
using UtilsORM.MySql_IotDataCenter;
using GateWayCloodService.Data;
using UtilsMQ;
using UtilsCache;
using UtilsMQ.Model;
using Models.Constant;

namespace GateWayCloodService.Mq
{
    public class ServiceRabbitMQ_Client_Helper
    {
        DBIotMqLog mqlog = new DBIotMqLog();
        DBIotSystemLogError logerror = new DBIotSystemLogError();
        static ConnectionFactory connectionFactory = null;
        static bool payBool = false;


        static IConnection connectionPay = null;
        static IModel channelpay = null;
        static ConnectionFactory connectionFactoryPay = null;
        static string EXCHANGE_NAME = MQEventEnum.EXCHANGE_NAME;// "my_exchange"; //要使用的exchange的名称
        static string EXCHANGE_TYPE = MQEventEnum.EXCHANGE_TYPE;// "topic"; //要使用的exchange的名称
        static string EXCHANGE_ROUTING_KEY = MQEventEnum.EXCHANGE_ROUTING_KEY;// "my_routing_key.#"; //exchange使用的routing-key
        static DateTime payExecuteTime = DateTime.Now;//心跳时间，用于重启消费




        /// <summary>
        /// 启动消费，判断 是否重启消费
        /// </summary>
        public void runPayMsg()
        {
            do
            {//消息无响应 或者20分钟内没有消费过，重启
                if (payBool == false || payExecuteTime < DateTime.Now.AddMinutes(-20))
                {
                    payMsg(MQEventEnum.MQServer_QueueName);
                    Thread.Sleep(5 * 1000);
                }
                else
                {
                    Thread.Sleep(55 * 1000);
                }

            } while (true);
        }
        /// <summary>
        /// 消息监听
        /// </summary>
        /// <param name="_queuename"></param>
        public void payMsg(object _queuename)
        {
            payBool = true;
            string queuename = (string)_queuename;

            try
            {

                if (connectionPay != null && connectionPay.IsOpen)
                {
                    connectionPay.Close();
                    connectionPay.Dispose();
                };
                Console.WriteLine($"启动mq pay {UtilAppsettingCache.getSetting("rabbitmq:mqVirtualHost")}");

                if (connectionPay == null || !connectionPay.IsOpen)
                {
                    //创建连接
                    connectionPay = connectionFactory.CreateConnection();
                }



                //连接关闭的时候
                //connectionPay.ConnectionShutdown += Connetion_ConnectionShutdown;
                //异常
                //connectionPay.CallbackException += Connetion_CallbackException;
                if (channelpay == null || !channelpay.IsOpen)
                {
                    //创建通道
                    channelpay = connectionPay.CreateModel();
                    channelpay.ExchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true, false, null);
                    //声明一个队列
                    channelpay.QueueDeclare(queuename, false, false, false, null);
                    //将queue绑定至某个exchange。一个exchange可以绑定多个queue
                    channelpay.QueueBind(queuename, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);
                }
                //事件基本消费者
                EventingBasicConsumer consumer = new EventingBasicConsumer(channelpay);
                //接收到消息事件
                consumer.Received += (ch, ea) =>
                {
                    payExecuteTime = DateTime.Now;//心跳时间
                    string message = Encoding.Default.GetString(ea.Body.ToArray());
                    channelpay.BasicAck(ea.DeliveryTag, false);
                    Task.Run(() =>
                   {
                       bool result = new MQPayEvent().payEvent(message);

                   });
                    Task.Run(() =>
                    {
                        ///写日志
                        mqlog.writeMQLog(message, "receive", "true");
                    });

                    //channelpay.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true); 拒绝信息，重回队列
                };
                //启动消费者 设置为手动应答消息
                channelpay.BasicConsume(queuename, false, consumer);


            }
            catch (Exception ex)
            {
                payBool = false;
                Console.WriteLine("payMsg Exception： " + ex);
                //new UtilsFileHelper().log_WriteMessageAppend(UtilsFileHelper.FILE_WEB_NAME + "_error", " payMsg 启动 Exception " + ex.ToString());
            }
        }







        public static IConnection connectionSend = null;
        static IModel sendchannel = null;
        static IBasicProperties props = null;
        


        public bool rabbitmqSendMsg(string queuename, string msg)
        {
            // mQReqModel.createTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"));
            // string msg = StringJsonSet(mQReqModel);



            try
            {

                if (connectionSend == null || !connectionSend.IsOpen)
                {
                    //创建连接
                    connectionSend = connectionFactory.CreateConnection();
                }
                if (sendchannel == null || !sendchannel.IsOpen)
                {                 //创建通道
                    sendchannel = connectionSend.CreateModel();
                    //sendchannel.ExchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true, false, null);

                    //增加设置消息超时
                    props = sendchannel.CreateBasicProperties();
                    props.ContentType = "text/plain";
                    props.DeliveryMode = 2;//1（nopersistent）非持久化，2（persistent）持久化
                    props.Expiration = "5000";//5秒 //"600000";//1000*60*10毫秒 10分钟
                    props.Persistent = true;
                }
                sendchannel.QueueDeclare(queuename, false, false, false, null);
                //sendchannel.QueueBind(queuename, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);

                var sendBytes = Encoding.UTF8.GetBytes(msg);


                //发布消息
                sendchannel.BasicPublish("", queuename, props, sendBytes);
                //sendchannel.Close();
                //sendchannel.Dispose();


                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("sendMsg Exception： " + ex);


                ///写日志
                mqlog.writeMQLog(msg, "send", "false");
                logerror.addSystemLogError("sendMsg mq发送失败queuename:" + queuename, ex.ToString());
                return false;
            }
        }




        /// <summary>
        /// 获取mq配置信息
        /// </summary>
        public ServiceRabbitMQ_Client_Helper()
        {
            if (connectionFactory == null)
            {
                string UserName = UtilAppsettingCache.getSetting("rabbitmq:mqUserName");// "notifier",//用户名
                string Password = UtilAppsettingCache.getSetting("rabbitmq:mqPassword");// "bjxNx6HSok",//密码
                string HostName = UtilAppsettingCache.getSetting("rabbitmq:mqHostName");// "192.168.197.217",//rabbitmq ip
                string Port = UtilAppsettingCache.getSetting("rabbitmq:mqPort");//  5672,
                string VirtualHost = UtilAppsettingCache.getSetting("rabbitmq:mqVirtualHost");//  "notifier"
                connectionFactory = ServiceRabbitMQ_Config.initFactory(UserName, Password, HostName, Port, VirtualHost);
            }
        }


        public static string StringJsonSet<T>(T data)
        {
            return JsonConvert.SerializeObject(data);
        }

    }

}
